package moodish.server;

import java.util.ArrayList;
import java.util.LinkedList;

import moodish.comm.ServerSideMessage;
import moodish.comm.component.ServerCommComponent;
import moodish.comm.component.ServerSideMessageComponent;

/**
 * The server of moodish network. According to the type of message received from servercomm the server sends the right message    
 * 
 * @author Goncalo, Ana, Bruno
 *
 */

public class Server implements MoodishServer{
	
	ArrayList<Client> listOfClients = new ArrayList<Client>();
	/**
	 * The method that starts the server and receive the serversidemessage from the servercomm    
	 * 
	 * @param serverComm    the serverComm from network that connects with the server
	 *
	 */
	
	
	
	@Override
	public void start(ServerCommComponent serverComm) {
		serverComm.start();

		while (true) {


			if (serverComm.hasNextMessage()){
				ServerSideMessage message =  serverComm.getNextMessage();
			
				//CLIENT_CONNECTED
				 if (message.getType() == ServerSideMessageComponent.Type.CLIENT_CONNECTED){
					boolean IsUser = false;
					// connect client 
					for (Client c: listOfClients){
						if (c.getClient().equals(message.getClientNickname())){
							System.out.println(" SERVER  Connecting Client " + message.getClientNickname());
							IsUser = true;
							c.setConnected();
						}
					}
					//Connect new client
					if (IsUser == false){
						listOfClients.add(new Client(message.getClientNickname()));
						System.out.println(" SERVER  Just created a new Client " + message.getClientNickname());
						for (Client c:listOfClients){
							if (c.getClient().equals(message.getClientNickname()))
								c.setConnected();
						}
					}
					//	send the message to all clients that he his connected 
					for (Client c: listOfClients){
						if (c.isConnected() && !c.getClient().equals(message.getClientNickname())){
							serverComm.sendClientConnected(c.getClient(), message.getClientNickname());
							System.out.println(message.getClientNickname()+ "client connected");
						}
					}
					// receive message from all the already connected clients
					for (Client c: listOfClients){
						if (c.getClient().equals(message.getClientNickname())){
							for (Client connected :listOfClients){
								if(connected.isConnected() && !c.getClient().equals(connected.getClient()))
									serverComm.sendClientConnected(c.getClient(), connected.getClient());
							}
						}
					}
				}	
				//CLIENT_DISCONNECTED
				else if (message.getType() == ServerSideMessageComponent.Type.CLIENT_DISCONNECTED){
					//client disconnected and remove all of his friends
					for (Client c:listOfClients){
						if (c.getClient().equals(message.getClientNickname())){
							c.setDisconnected();
							System.out.println(" SERVER  disconnecting client " + message.getClientNickname());
							serverComm.disconnectClient(message.getClientNickname());
							c.removeAllFriends();	  						
							}						
					  }
		
					//inform all connected clients that this client is disconnected
					for (Client c: listOfClients){
						if (c.isConnected() && !c.getClient().equals(message.getClientNickname()))
							serverComm.sendClientDisconnected(c.getClient(),message.getClientNickname());
							   if(c.IsFriend(message.getClientNickname())){
							      c.removeFriend(message.getClientNickname());
							    }
						}	
				 }
				//Friendship
				else if (message.getType() == ServerSideMessageComponent.Type.FRIENDSHIP){
					System.out.println("Server: Recebi um pedido de freindship");
					for (Client c: listOfClients){
						if (c.getClient().equals(message.getClientNickname())){
							//If not in his list of friends add the new friend to the list and send a message to the new friend
							if (!c.IsFriend(message.getClientNickname())){ 
								c.addFriend(message.getClientNickname());
								System.out.println("Server: Erro 1");
								System.out.println(" SERVER  adding friend " + message.getPayload());
								serverComm.sendNewFriendship(message.getPayload(), message.getClientNickname());
							}
							else
								//if in the list, it sends one error message
								serverComm.sendError(message.getPayload(),message.getClientNickname() + " is already a friend");
						}
						if (c.getClient().equals(message.getPayload())){
							if (!c.IsFriend(message.getClientNickname())){
							   c.addFriend(message.getClientNickname());
							   System.out.println("Server: Erro 2");
							   System.out.println(" SERVER  adding friend " + message.getClientNickname());
							   serverComm.sendNewFriendship(message.getClientNickname(), message.getPayload());
							}   
						}	
					  }
					}
					//MOODISH_MESSAGE
					else if (message.getType() == ServerSideMessageComponent.Type.MOODISH_MESSAGE) {
						LinkedList<String> friends = new LinkedList<String>();
						//return the list of friends
						for (Client c: listOfClients){
							if (c.getClient().equals(message.getClientNickname())){
								friends = c.getFriends();
							}
						}
						//sends the message to all of his friends 
						for (String f : friends){
							System.out.println(" SERVER  sending mood to " + f.toString());
							serverComm.sendMoodishMessage(message.getClientNickname(), f.toString(), message.getPayload());						
						}
					}	
				  	
				//UNFRIENDSHIP
					else if (message.getType() == ServerSideMessageComponent.Type.UNFRIENDSHIP){
						for (Client c: listOfClients){
							if (c.getClient().equals(message.getClientNickname())){
								
								//If is in the list of friends remove the and send a message of unfriendship to the client unfriended  
								if(c.IsFriend(message.getPayload())){
									c.removeFriend(message.getPayload());
									System.out.println(" SERVER  unfriendshiping " + message.getPayload());
									serverComm.sendNewUnfriendship(message.getPayload(), message.getClientNickname());
								}
								else
									//If not in the list, sends one error message
									serverComm.sendError(message.getPayload(),message.getClientNickname()+ " is not a friend");
							}
							//removes the client from the friends list not his list
							else if (c.getClient().equals(message.getPayload())){
								c.removeFriend(message.getClientNickname());
							}
						}
					}	
				
			}
        }
	}	
 }
